上一篇我们自定义了一个流式布局的ViewGroup
,我们为了熟悉自定义ViewGroup
,就继续自定义ViewGroup
。这篇的内容是是仿照酷狗的侧滑菜单。
我们写代码之前,先想清楚是怎么实现,解析实现的步骤。实现侧滑的方式很多种,在这里我选择继承HorizontalScrollView
,为什么继承这个呢?因为继承这个的话,我们就不用写childView
的move meause layout
,这样就节约了很大的代码量和事件,因为内部HorizontalScrollView
已经封装好了。我们在这个控件里面放置两个childView
,一个是menu
,一个是content
。然后我们处理拦截和快速滑动事件就可以了。思路想清楚了我们就开始撸码。
首先我们自定义一个属性,用于打开的时候content
还有多少可以看到,也就是打开的时候menu
距离右边的距离。
1 | <?xml version="1.0" encoding="utf-8"?> |
在初始化的时候我们通过menuRightMargin
属性获取menu
真正的宽度
1 | public SkiddingMenuLayout(Context context) { |
接着我们在布局加载完毕的时候我们指定menu
和content
的宽度
1 | //xml 布局解析完毕回调的方法 |
这里有一个细节,我们在刚进入的时候,菜单默认是关闭的,所以我们需要调用scrollTo()
函数移动一下位置,但是发现在onFinishInflate()
函数里面调用没有作用,这个是为什么呢?因为我们在xml
加载完毕之后,才会真正的执行View
的绘制流程,这时候调用scrollTo()
这个函数其实是执行了代码的,但是在onLaout()
摆放childView
的时候,又默认回到了(0,0)
位置,所以我们应该在onLayout()
之后调用这个函数
1 |
|
初始化完毕了,接下来我们进行事件的拦截,MOVE
的时候相应滑动事件,UP
的时候判断是关闭还是打开,然后调用函数即可
1 |
|
到这的话,滑动事件和打开关闭事件都完成了,接下来我们就处理一个效果的问题,这里当从左往右滑动的时候,是慢慢打开菜单,这时候content
是有一个慢慢的缩放,menu
有一个放大和透明度变小,而反过来关闭菜单的话就是相反的效果,content
慢慢放大,menu
缩小和透明度变大。这里还有一个细节,就是menu
慢慢的退出和进入,滑动的距离不是和移动的距离相同的,所以这里还有一个平移。接下来重写onScrollChanged()
函数,然后计算出一个梯度值来做处理
1 | //滑动改变触发 |
这样的话我们就完成了效果,但是我们还有几个细节没有处理,首先是快速滑动的问题,还有一个是当打开menu
的时候,点击content
需要关闭菜单,而不是相应对应的事件。接下来我们对这两个问题进行处理。
快速滑动问题,这个问题我们采用GestureDetector
这个类来做处理,这个类可以处理很多收拾问题:
1 |
|
这里我们主要是响应onFling()
这个函数,然后判断当前是打开还是关闭状态,在根据快速滑动的手势来执行打开还是关闭的操作:
1 |
|
接下来处理menu
打开状态下点击content
关闭menu
,这里我们需要用到onInterceptTouchEvent
。当打开状态的时候,我们就把这个事件拦截,然后关闭菜单即可。但是这里有一个问题,当我们拦截了DOWN
事件之后,后面的MOVE UP
事件都会被拦截并且相应自身的onTouchEvent
事件,所以这里我们需要添加一个判断值,判断是否拦截,然后让其onTouchEvent
是否继续执行操作
1 |
|
根据我们提出需求,然后分析需求,再完成需求。这一步步我们慢慢进行渗透,最终完成效果,完成之后你会发现其实也就那么一回事。当我们有新需求的时候,我们应该不要恐惧,应该欣然乐观的接收,再慢慢分析,最终完成。这样的话我们才能提高我们的技术。
v1.5.2